package calao.client;

import java.util.Vector;

import calao.client.ServiceCallback;
import calao.client.i18n.Text;
import calao.client.ui.ConfirmBox;
import calao.client.ui.Form;
import calao.client.ui.HasLinks;
import calao.client.ui.HasTitle;
import calao.client.ui.InvalidInputException;
import calao.client.ui.Link;
import calao.client.ui.MappedListBox;
import calao.client.ui.NumberedListBox;
import calao.client.util.Arrays;
import calao.client.util.IntMap;

import com.google.gwt.user.client.ui.TextBox;

public class ProfileForm 
extends Form 
implements HasTitle, HasLinks
{

	final ProfileTable list;
	
	ProfileInfo profile;
	
	final Text text = Desktop.getDesktop().text;
	final Vector permList = Desktop.getDesktop().permList;
	
	TextBox name = calao.client.ui.Widgets.newTextBox();
	
	MappedListBox permBox = new MappedListBox(getPermissionMap(), NumberedListBox.CHECK_LIST) {
		protected String getItemText(Object item) {
			return ((Permission)item).title;
		}		
	};

	class DeleteLink extends Link {
		DeleteLink() {
			super(text.delete());
		}
		protected void onClick() {
			delete();
		}
	}
	
	ProfileForm(ProfileTable list)
	{
		this(CREATE, list, new ProfileInfo());
		setTitle(text.newProfile());
	}

	ProfileForm(ProfileTable list, ProfileInfo profile)
	{
		this(VIEW, list, profile);
		setTitle(text.profileX(profile.name));
	}
	
	private ProfileForm(int action, ProfileTable list, ProfileInfo profile)
	{
		super(action, true);
		this.list = list;
		this.profile = profile;
		build();
		reset();
		refresh();
	}
	
	private void build()
	{
		add(text.name(), name);
		add(text.permissions(), permBox);
	}

	public void reset()
	{
		name.setText(profile.name);
		int[] select = new int[permList.size()];
		int count = 0;
		for (int i=0; i<permList.size(); i++) {
			Permission perm = (Permission)permList.get(i);
			if (Arrays.contains(profile.permissionNames, perm.name)) select[count++] = i;
		}
		permBox.setNumberSelected(Arrays.copyOf(select, count));
		permBox.refresh();
	}

	public void saveChanges()
	{
		final ProfileInfo newObj = new ProfileInfo(profile);
		copyFieldValuesTo(newObj);
		Desktop.getDesktop().memberService.save(newObj, new ServiceCallback() {
			protected void onReturn(Object obj) {
				ProfileForm.this.profile = newObj;
				list.modified(newObj);
				setChangesSaved();
			}
			protected void onThrow(Throwable caught) {
				reset();
			}
		});
	}
	
	void copyFieldValuesTo(ProfileInfo obj)
	{
		obj.name = name.getText();
		int[] select = permBox.getSelectedList();
		String[] perms = new String[select.length];
		for (int i=0; i<perms.length; i++) {
			Permission perm = (Permission)permList.get(select[i]);
			perms[i] = perm.name;
		}
		obj.permissionNames = perms;
	}
	
	public void create()
	{
		copyFieldValuesTo(profile);
		Desktop.getDesktop().memberService.save(profile, new ServiceCallback() {
			protected void onReturn(Object obj) {
				list.created(profile);
				Desktop.getDesktop().popView();
			}
		});		
	}
	
	public void validate() throws InvalidInputException
	{
		if (name.getText().length()<=0) throw new InvalidInputException();
	}

	public Link[] getLinks() 
	{
		return new Link[] { new DeleteLink() };
	}
	
	public void delete()
	{
		ConfirmBox box = new ConfirmBox() {
			public void confirm() {
				Desktop.getDesktop().memberService.delete(profile, new ServiceCallback() {
					protected void onReturn(Object obj) {
						list.deleted(profile);
						Desktop.getDesktop().popView();				
					}
				});
			}
		};
		box.setText(text.delete());
		box.setMessage(text.confirmProfileDeletion(profile.name));
		box.center();
	}
	
	IntMap getPermissionMap()
	{
		IntMap map = new IntMap();
		for (int i=0; i<permList.size(); i++) {
			map.put(i, permList.get(i));
		}
		return map;
	}
	
}
